package com.yjhh.tilemap.utils;

import com.yjhh.tilemap.vo.TileMapInfo;

/**
 * Description: 地图经纬度和瓦片转化
 *
 * @JDK Version:1.8.0_40
 * Version: V1.0
 * Author: spring
 * Date: 2017/8/14
 */
public class MapTools {

    /**
     * 经度到像素X值
     */
    public static double lngToPixel(double lng, int zoom) {
        return (lng + 180) * (256 << zoom) / 360;
    }

    //像素X到经度
    public static double pixelToLng(double pixelX, int zoom) {
        return pixelX * 360 / (256 << zoom) - 180;
    }

    //纬度到像素Y
    public static double latToPixel(double lat, int zoom) {
        double siny = Math.sin(lat * Math.PI / 180);
        double y = Math.log((1 + siny) / (1 - siny));
        return (128 << zoom) * (1 - y / (2 * Math.PI));
    }

    //像素Y到纬度
    //#define E 2.7128  // 当然还可以更精确
    public static double pixelToLat(double pixelY, int zoom) {
        double y = 2 * Math.PI * (1 - pixelY / (128 << zoom));
        double z = Math.pow(Math.E, y);
        double siny = (z - 1) / (z + 1);
        return Math.asin(siny) * 180 / Math.PI;
    }

    public static String getTileNumber(final double lat, final double lon, final int zoom) {
        TileMapInfo tileMapInfo = getTileMapInfo(lat, lon, zoom);
        return ("" + zoom + "/" + tileMapInfo.getXtile() + "/" + tileMapInfo.getYtile());
    }

    public static TileMapInfo getTileMapInfo(final double lat, final double lon, final int zoom) {
        int xtile = (int) Math.floor((lon + 180) / 360 * (1 << zoom));
        int ytile = (int) Math.floor((1 - Math.log(Math.tan(Math.toRadians(lat)) + 1 / Math.cos(Math.toRadians(lat))) / Math.PI) / 2 * (1 << zoom));
        if (xtile < 0)
            xtile = 0;
        if (xtile >= (1 << zoom))
            xtile = ((1 << zoom) - 1);
        if (ytile < 0)
            ytile = 0;
        if (ytile >= (1 << zoom))
            ytile = ((1 << zoom) - 1);

        return new TileMapInfo(zoom, xtile, ytile);
    }

}
